package com.shigen.demo.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import com.shigen.demo.config.ConfigProperty;
import java.nio.charset.StandardCharsets;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TokenUtil {

  @Resource
  private ConfigProperty configProperty;

  private static final int TOKEN_LEN = 10;

  public String getToken() {
    //构建 key的最小长度必须为 8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    String token = RandomUtil.randomString(TOKEN_LEN);
    return des.encryptHex(token);
  }

  public String getTokenWithTimestrap() {
    //构建 key的最小长度必须为8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    String token = RandomUtil.randomString(TOKEN_LEN) + DateUtil.currentSeconds();
    return des.encryptHex(token);
  }

  public String parseToken(String token) {
    //构建 key的最小长度必须为8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    return des.decryptStr(token);
  }

  /**
   * 获得真实的token，已去掉10位时间戳
   *
   * @param token
   * @return
   */
  public String getRealToken(String token) {
    String parseToken = this.parseToken(token);
    int length = parseToken.length();
    try {
      String substring = parseToken.substring(0, length - 10);
      log.info("{}: realToken: {}", DateUtil.now(), substring);
      return substring;
    } catch (IndexOutOfBoundsException e) {
      log.error("token解析错误，exception: {}", e.getMessage());
    }
    return "";
  }

  public Boolean verify(String token) {
    String s = parseToken(token);
    // 最后10位为时间戳的数字
    String timestrap = s.substring(s.length() - 10);
    boolean aLong = NumberUtil.isLong(timestrap);
    if (!aLong) {
      return false;
    }
    // 获得当前时间戳比较
    return DateUtil.currentSeconds() - Long.parseLong(timestrap) <= configProperty.getTokenDelay();
  }
}
